<script lang="jsx">
import { defineComponent, ref, computed, nextTick, watch } from 'vue'
import { getTableConfig, getTableColumnConfig, convertTableData } from '../utils/table'
import { intersection, template } from 'lodash-es'
import { usePermissionStoreWithOut } from '@/store/modules/permission'
import { infiniteScroll } from '@/modules/utils/directives'
import dayjs from 'dayjs'
import CellRender from './CellRender.vue'
import EditRender from './EditRender.vue'

export default defineComponent({
  name: 'MetaTable',
  components: { CellRender, EditRender },
  directives: {
    infiniteScroll
  },
  props: {
    meta: {
      type: Array,
      default: () => []
    },
    list: {
      type: Array,
      default: () => []
    },
    selection: {
      // 已选中列表
      type: Array,
      default: () => []
    },
    mergeCells: {
      type: Array,
      default: () => []
    },
    operations: {
      type: Array,
      default: () => []
    },
    config: {
      type: Object,
      default: () => ({})
    },
    showSelect: {
      type: Boolean,
      default: true
    },
    showOperation: {
      type: Boolean,
      default: false
    }
  },
  setup(props, { emit, slots, expose }) {
    const permissionStore = usePermissionStoreWithOut()
    const tableRef = ref()
    const onEditClosed = async ({ row, column, $table }) => {
      await nextTick()
      const field = column.field
      console.log(field)
      if ($table.isUpdateByRow(row, field)) {
        // 提交前校验
        const fieldConfig = props.meta.find((f) => f.key === field)
        if (fieldConfig && fieldConfig.validate) {
        }
        const data = props.meta.reduce(
          (t, c) => {
            if (c.editable && c.display) {
              t[c.key] = row[c.key]
            }
            return t
          },
          { id: row.id }
        )
        emit('editSave', data, row)
        // 局部更新单元格为已保存状态
        $table.reloadRow(row, null, field)
      }
    }
    // const reloadRow = (row, field) => {
    //   tableRef.value?.reloadRow(row, null, field)
    // }
    const handleSelectionChange = ({ checked }) => {
      const records = tableRef.value.getCheckboxRecords()
      const oldRecords = [...props.selection]
      emit('selection-change', records, oldRecords, checked)
      emit('update:selection', records)
    }
    const showDelete = (item) => {
      emit('deleteRow', item)
    }
    const showEdit = (item) => {
      emit('editRow', item)
    }
    const cellOperation = (col, item) => {
      emit('cell-operation', col, item)
    }
    // 获取修改信息
    const getModifyData = () => {
      const $table = tableRef.value?.tableRef
      if ($table) {
        const insertList = $table.getInsertRecords()
        const removeList = $table.getRemoveRecords()
        const updateList = $table.getUpdateRecords()
        return {
          insertList,
          removeList,
          updateList
        }
      }
      return {}
    }
    // 刷新单元格
    const reloadRow = (row, data, field) => {
      tableRef.value?.reloadRow(row, data, field)
    }
    // 取消选择
    const clearSelection = () => {
      return tableRef.value?.clearCheckboxRow()
    }
    // 设置行选择
    const setSelection = (row, checked) => {
      return tableRef.value?.setCheckboxRow(row, checked)
    }
    // 获取checkbox选择的行
    const getSelectionList = () => {
      return tableRef.value?.getCheckboxRecords()
    }
    // 设置行编辑
    const setEditRow = (row) => {
      tableRef.value?.setEditRow(row)
    }
    // 获取行编辑状态
    const isActiveStatus = (row) => {
      return tableRef.value?.isEditByRow(row)
    }
    // 获取行数据是否变化
    const isUpdateByRow = (row) => {
      return tableRef.value?.isUpdateByRow(row)
    }
    // 取消行编辑状态
    const cancelRowEdit = (row) => {
      const $table = tableRef.value
      if ($table) {
        $table.clearEdit()
        // 还原行数据
        $table.revertData(row)
      }
    }
    // 保存行编辑状态
    const saveRowEdit = (row) => {
      const $table = tableRef.value
      if ($table) {
        $table.clearEdit()
        // 还原行数据
        $table.reloadRow(row, {})
      }
    }
    // 可编辑状态，校验
    const editValidate = async (row) => {
      const $table = tableRef.value
      if ($table) {
        return $table.validate(row || true)
      }
      return Promise.resolve(true)
    }
    // 可编辑状态，清理校验
    const clearValidate = async () => {
      const $table = tableRef.value
      if ($table) {
        $table.clearValidate()
      }
    }
    expose({
      tableRef,
      getModifyData,
      reloadRow,
      getSelectionList,
      clearSelection,
      setEditRow,
      isActiveStatus,
      isUpdateByRow,
      cancelRowEdit,
      saveRowEdit,
      editValidate,
      clearValidate,
      setSelection
    })
    watch(
      () => props.meta,
      () => {
        if (props.config?.['edit-config']) {
          // initRemoteValues(props.meta)
          // initAutocomplete(props.meta)
        }
      }
    )
    watch(
      () => props.list,
      () => {
        clearSelection()
      }
    )
    watch(
      () => props.selection,
      (rows) => {
        const $table = tableRef.value
        $table.clearCheckboxRow()
        $table.setCheckboxRow(rows, true)
      },
      {
        deep: true
      }
    )
    if (props.meta) {
      if (props.config?.['edit-config']) {
        // initRemoteValues(props.meta)
        // initAutocomplete(props.meta)
      }
      console.log('meta:', props.meta)
      const operatorRender = (scope) => {
        return (
          <div>
            <el-link effect="dark" style="cursor: pointer" onClick={() => showEdit(scope.row)}>
              编辑
            </el-link>
            <el-link
              effect="dark"
              type="danger"
              style="cursor: pointer; margin-left: 5px"
              onClick={() => showDelete(scope.row)}
            >
              删除
            </el-link>
          </div>
        )
      }
      const tableData = computed(() => convertTableData(props.list, props.meta))
      const tableConfig = computed(() => getTableConfig(props.config))
      const hasPermiEdit = computed(() => {
        const o = props.operations?.find((m) => m.key === 'edit')
        const roles = permissionStore.getUserInfo?.roles || []
        if (o && (!o.roles || intersection(o.roles || [], roles).length > 0)) {
          return true
        } else {
          return false
        }
      })
      console.log(tableConfig.value, hasPermiEdit.value)
      // 行样式配置
      const rowStyleConfigs = props.meta?.filter((col) => col.rowStyle) || []
      const rowStyle = ({ row }) => {
        for (let i = 0; i < rowStyleConfigs.length; i++) {
          const col = rowStyleConfigs[i]?.rowStyle
          const ary = [col].flat()
          for (let j = 0; j < ary.length; j++) {
            if (
              ary[j]?.visible &&
              [ary[j].visible]
                .flat()
                .some(
                  (vis) =>
                    row &&
                    (typeof vis === 'string'
                      ? template(vis)({ ...row, $dayjs: dayjs }) == 'true'
                      : Object.keys(vis).every((key) => [vis[key]].flat().includes(row[key])))
                )
            ) {
              return ary[j].style
            }
          }
        }
      }
      // 单元格样式配置
      const cellStyleConfigs = props.meta?.filter((col) => col.cellStyle) || []
      const cellStyle = ({ row, column }) => {
        const col = cellStyleConfigs.find((x) => x.key === column.field)?.cellStyle
        const ary = [col].flat()
        for (let j = 0; j < ary.length; j++) {
          if (
            ary[j]?.visible &&
            [ary[j].visible]
              .flat()
              .some(
                (vis) =>
                  row &&
                  (typeof vis === 'string'
                    ? template(vis)({ ...row, $dayjs: dayjs }) == 'true'
                    : Object.keys(vis).every((key) => [vis[key]].flat().includes(row[key])))
              )
          ) {
            return ary[j].style
          }
        }
      }
      const mergeCells = computed(
        () =>
          (props.showSelect
            ? props.mergeCells.map((c) => ({ ...c, col: c.col + 1 }))
            : props.mergeCells) || []
      )
      console.log('mergeCells.value===>', mergeCells.value)
      return () => (
        <vxe-table
          ref={tableRef}
          data={tableData.value}
          {...tableConfig.value}
          border={mergeCells.value.length > 0 ? true : false}
          stripe={mergeCells.value.length > 0 ? false : true}
          merge-cells={mergeCells.value}
          row-style={rowStyle}
          cell-style={cellStyle}
          onCheckboxChange={handleSelectionChange}
          onCheckboxAll={handleSelectionChange}
          onEditClosed={onEditClosed}
          v-slots={{
            empty: () => <el-empty description="暂无数据" />
          }}
        >
          {props.showSelect && <vxe-column type="checkbox" width="50" fixed="left" />}
          {props.meta.map(
            (col, idx) =>
              col.display && (
                <vxe-column
                  title={col.name}
                  key={idx}
                  width={col.width}
                  field={col.key}
                  show-overflow={
                    typeof col.showOverflow === 'boolean'
                      ? col.showOverflow
                      : col.showOverflow || 'tooltip'
                  }
                  edit-render={{
                    enabled: col.type !== 'color' && col.editable && hasPermiEdit.value
                  }}
                  {...getTableColumnConfig(col)}
                  class-name={() => (col.preview ? `preview-${col.preview}` : '')}
                >
                  {{
                    default: (scope) =>
                      col.operation ? (
                        <span
                          class="table-cell-operation"
                          onClick={() => cellOperation(col, scope.row)}
                        >
                          <Icon icon="svg-icon:dialog" size={18} />
                          <CellRender row={scope.row} col={col} meta={props.meta}></CellRender>
                        </span>
                      ) : (
                        <CellRender row={scope.row} col={col} meta={props.meta}></CellRender>
                      ),
                    edit: (scope) => (
                      <EditRender row={scope.row} col={col} meta={props.meta}></EditRender>
                    )
                  }}
                </vxe-column>
              )
          )}
          {props.showOperation && (
            <vxe-column
              title="操作"
              fixed="right"
              show-overflow={false}
              width={tableConfig.value['operation-width']}
            >
              {{
                default: (scope) =>
                  slots['operator'] ? slots['operator'](scope) : operatorRender(scope)
              }}
            </vxe-column>
          )}
        </vxe-table>
      )
    }
    return {}
  }
})
</script>
<style lang="less">
.vxe-select--panel.is--transfer {
  z-index: 3001 !important;
}
.vxe-table {
  .vxe-body--column.preview-thumbnail {
    & > .vxe-cell {
      height: 100%;
    }
    .el-link {
      width: 100%;
      height: 100%;
      .el-link__inner {
        width: 100%;
        height: 100%;
      }
      img {
        width: auto;
      }
    }
  }
}
</style>
